package com.acmen.easyapi.aspect;

import com.acmen.easyapi.annotation.RestApi;
import com.acmen.easyapi.util.ResponseUtil;
import com.acmen.easyapi.util.StringUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author acmen
 * 通过注解切面controller服务
 * @date 2022-07-02
 */
@Aspect
@Order(9999)
@Component
public class RefactorResponseAspect {
    private static ThreadLocal<String> flag = new ThreadLocal<String>();

    /**
     * 对通过注解进行切面controller服务的方法进行切面处理
     * @param joinPoint 切面方法的联结点
     * @param restApi 注解对象
     * @return 切面处理后的返回值
     * @throws Throwable 异常
     */
    @Around("@annotation(restApi)")
    public Object around(ProceedingJoinPoint joinPoint, RestApi restApi) throws Throwable {
        if (flag.get() != null) {
            // 防止接口服务相互调用被切入多次
            return joinPoint.proceed();
        }
        // 获取HttpServletRequest对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        // 获取客户端信息
        String client = getClient(request);
        // 如果客户端信息为空，则直接执行后续代码
        if(StringUtil.isEmpty(client)){
            return joinPoint.proceed();
        }
        // 设置标记为"1"
        flag.set("1");
        try {
            // 执行目标方法，并获取返回值
            Object returnValue = joinPoint.proceed();
            // 如果客户端信息为空，则直接返回返回值
            if(StringUtil.isEmpty(client)){
                return returnValue;
            }else{
                // 否则，使用返回值和客户端信息进行重定向
                return ResponseUtil.refactorResponse(returnValue, client);
            }
        }finally {
            // 删除标记
            flag.remove();
        }

    }

    /**
     * 获取客户端信息
     * @param request HTTP请求对象
     * @return 客户端信息
     */
    public static String getClient(HttpServletRequest request) {
        String client = request.getHeader("Http-Client"); // 从请求头中获取"Http-Client"字段的值，赋给client变量
        if (client == null || "".equals(client.trim())) { // 如果client为null或者client经trim处理后为空字符串
            client = request.getParameter("Http-Client"); // 从请求参数中获取"Http-Client"字段的值，赋给client变量
        }
        if (client == null || "".equals(client.trim())) { // 如果client为null或者client经trim处理后为空字符串
            client = (String) request.getAttribute("Http-Client"); // 从请求属性中获取"Http-Client"字段的值，强制转换为String类型，赋给client变量
        }
        return client; // 返回client变量的值作为方法的返回值

    }
}
